// i.r(t), i.d(t, { DeletedObject: () => s.F, default: () => P })
import DeletedObject from "../object/DeletedObject"
import Module from "./Module"
import { SaveCommand, GetUnpublishedDeletionsCommand } from "../command/data.command"
import Store from "../storage/Store"
function d(e) {
  return {
    id: e.id,
    label: e.label,
    object_id: e.objectId,
    object_type: e.objectType,
    created: dateISO(e.created),
    json_string: JSON.stringify(e.value)
  }
}
function c(e: Record<any, any>) {
  const t = {}
  for (const i of Object.values(e)) {
    const e = d(i)
    e && (t[i.id] = e)
  }
  return t
}
function u(e) {
  const t = e.id,
    i = e.label,
    n = e.object_id,
    r = e.object_type,
    o = getDate(e.created)
  let a
  try {
    a = JSON.parse(e.json_string)
  } catch (e) {}
  if (!(t && n && r && a)) return null
  return new DeletedObject({
    id: t,
    label: i,
    objectId: n,
    objectType: r,
    created: o,
    value: a
  })
}
function p(e) {
  const t = {}
  for (const i in e) {
    const s = u(e[i])
    s && (t[i] = s)
  }
  return t
}
class TrashStore extends Store.JsonStore {
  constructor(e, t, i) {
    super({
      queue: t,
      path: `${i}/api/v1/jsonstore/model/trash/${e}`,
      batchUpdate: !0,
      deserialize: p,
      serialize: c
    })
  }
}
import Data from "../object/Data"
import ObservableMap from "../observer/observable.map"
import funcUtil from "../utils/func.util"
import Logger from "../utils/Logger"
const v = new Logger("TrashData")
class TrashData extends Data {
  trash: ObservableMap<any>
  registry: Map<any, any>
  constructor(e?) {
    super(), (this.trash = new ObservableMap()), (this.registry = new Map()), e && this.add(...Object.values(e))
  }
  get(e) {
    return this.trash.get(e)
  }
  add(...e) {
    this.trash.atomic(() => {
      for (const t of e)
        t.atomic(() => {
          for (; !t.id || this.trash.has(t.id); ) (t.id = funcUtil.randomStr(11)), t.commit()
        }),
          this.trash.set(t.id, t)
    }),
      this.commit()
  }
  create(e, t) {
    const i = this.registry.get(e)
    if (!i) return void v.debug(`Unsupported type added to trash: ${e}`)
    const s = i.create(t)
    return this.add(s), s
  }
  restore(e) {
    const t = this.trash.get(e),
      i = this.registry.get(t.objectType)
    if (!i) throw new Error(`Can't restore unsupported type ${t.objectType}`)
    return i.restore(t)
  }
  register(e) {
    v.debug(`Registered type ${e.objectType}`)
    const { objectType: t } = e
    this.registry.has(t) ? v.debug(`Type ${t} already registered`) : this.registry.set(t, e)
  }
  unregister(e) {
    return v.debug(`Unregistered type ${e}`), this.registry.delete(e)
  }
  isSupported(e) {
    return this.registry.has(e)
  }
}

import { RestoreDeletedObjectCommand, RegisterDeletedObjectTypeCommand } from "../command/object.command"
import { createSubscription } from "../utils/Subscription"
import { dateISO, getDate } from "../utils/date.util"
import dataTypeEnum from "../enum/dataType.enum"
const S = new Logger("Trash")
export default class TrashModule extends Module {
  engine: any
  store: TrashStore
  data: TrashData
  constructor() {
    super(...arguments), (this.name = "trash")
  }
  async init(e, t) {
    const { modelId: i, queue: s, baseUrl: n } = e,
      { market: o, commandBinder: h } = t
    ;(this.engine = t),
      (this.store = new TrashStore(i, s, n)),
      (this.data = new TrashData()),
      o.register(this, TrashData, this.data),
      this.bindings.push(
        h.addBinding(RegisterDeletedObjectTypeCommand, async e => this.registerDeletedObject(e)),
        h.addBinding(RestoreDeletedObjectCommand, async ({ id: e }) => this.restore(e))
      )
  }
  dispose(e) {
    super.dispose(e), e.market.unregister(this, TrashData)
  }
  async registerDeletedObject(e) {
    const { objectType: t } = e
    return createSubscription(
      () => this.data.register(e),
      () => this.data.unregister(t),
      !0
    )
  }
  async backup() {
    const { commandBinder: e } = this.engine,
      t = await e.issueCommand(new GetUnpublishedDeletionsCommand()),
      i = {}
    for (const e in t)
      this.data.isSupported(e) &&
        t[e].forEach(t => {
          const s = this.data.create(e, t)
          s && (i[s.id] = s)
        })
    if (Object.keys(i).length) return this.store.update(i)
  }
  async restore(...e) {
    const t = new Set()
    for (const i of e) {
      const e = this.data.get(i)
      S.debug(`Restoring ${e.objectType} ${e.id}`),
        Object.values(dataTypeEnum).includes(null == e ? void 0 : e.objectType) && t.add(e.objectType),
        this.data.restore(i)
    }
    if (t.size > 0) return this.engine.commandBinder.issueCommand(new SaveCommand({ dataTypes: [...t] }))
  }
}
// const P = TrashModule
// export default {
//   DeletedObject: s.F,
//   default: P
// }
